
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       xrce_dds.c
  * @author     baiyang
  * @date       2022-3-31
  ******************************************************************************
  */

/*----------------------------------include-----------------------------------*/
#include "xrce_dds.h"
#include "xrce_dds_topic.h"
#include "xrce_dds_transport.h"

#include <rtthread.h>

#include <common/microbee.h>
#include <common/console/console.h>
/*-----------------------------------macro------------------------------------*/
#define PARTICIPANT_ID 0
#define SUBSCRIBER_ID  0
#define PUBLISHER_ID   0
/*----------------------------------typedef-----------------------------------*/

/*---------------------------------prototype----------------------------------*/

/*----------------------------------variable----------------------------------*/
uint16_t __xrce_dds_object_id_start = 1;

XrceDDS xrce_dds;

static rt_thread_t thread_dds_handle;
/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
/**
  * @brief       
  * @param[in]   
  * @param[out]  
  * @retval      
  * @note        
  */
bool xrce_dds_init()
{
    if (!xrce_dds_transport_have_device()) {
        return false;
    }

    // Transport
    uxr_set_custom_transport_callbacks(
        &xrce_dds.xrce_dds_transport,
        true,
        xrce_dds_transport_open,
        xrce_dds_transport_close,
        xrce_dds_transport_write,
        xrce_dds_transport_read);

    if (!uxr_init_custom_transport(&xrce_dds.xrce_dds_transport, NULL))
    {
        console_printf("[xrce_dds]: Error at create transport.\n");
        return false;
    }

    // Session
    uxr_init_session(&xrce_dds.xrce_dds_session, &xrce_dds.xrce_dds_transport.comm, 0xAAAABBBB);
    uxr_set_topic_callback(&xrce_dds.xrce_dds_session, xrce_dds_on_topic, NULL);
    if (!uxr_create_session(&xrce_dds.xrce_dds_session))
    {
        console_printf("Error at create session.\n");
        return false;
    }

    // Streams
    // 使用尽力而为的输入、输出流
    xrce_dds.besteffort_out = uxr_create_output_best_effort_stream(&xrce_dds.xrce_dds_session, xrce_dds.output_best_effort_stream_buffer, XRCE_DDS_BUFFER_SIZE);
    xrce_dds.besteffort_in = uxr_create_input_best_effort_stream(&xrce_dds.xrce_dds_session);

    // Create entities
    xrce_dds.participant_id = uxr_object_id(PARTICIPANT_ID, UXR_PARTICIPANT_ID);
    uint16_t participant_req =
            uxr_buffer_create_participant_bin(&xrce_dds.xrce_dds_session, xrce_dds.besteffort_out, xrce_dds.participant_id, 0, "microbee",
                    UXR_REPLACE);

    xrce_dds.subscriber_id = uxr_object_id(SUBSCRIBER_ID, UXR_SUBSCRIBER_ID);
    uint16_t subscriber_req = uxr_buffer_create_subscriber_bin(&xrce_dds.xrce_dds_session, xrce_dds.besteffort_out, xrce_dds.subscriber_id, xrce_dds.participant_id,
                    UXR_REPLACE);

    xrce_dds.publisher_id = uxr_object_id(PUBLISHER_ID, UXR_PUBLISHER_ID);
    uint16_t publisher_req = uxr_buffer_create_publisher_bin(&xrce_dds.xrce_dds_session, xrce_dds.besteffort_out, xrce_dds.publisher_id, xrce_dds.participant_id,
                    UXR_REPLACE);

    uxr_run_session_time(&xrce_dds.xrce_dds_session, 0);

    // 延时5毫秒，使串口发送线程有时间将xrc dds客户端创建参与者、订阅者、发布者的请求发送到代理端
    rt_thread_mdelay(5);

    xrce_dds_topic_init();

    xrce_dds.initialization = true;

    return true;
}

static inline bool xrce_dds_run()
{
    if (!xrce_dds.initialization) {
        return false;
    }

    return xrce_dds_topic_run();
}


/**
  * @brief       
  * @param[in]     
  * @param[out]  
  * @retval      
  * @note        
  */
static void xrce_dds_entry(void *parameter)
{
    bool dds_init_success = xrce_dds_init();

    while(dds_init_success)
    {
        if (!xrce_dds_run()) {
            break;
        }

        rt_thread_mdelay(2);
    }

    // Delete resources
    if (dds_init_success) {
        uxr_delete_session(&xrce_dds.xrce_dds_session);
        //uxr_close_custom_transport(&xrce_dds.xrce_dds_transport);
    }
}

static int task_dds_init(void)
{
    rt_err_t res = -RT_ERROR;

    thread_dds_handle = rt_thread_create("dds",
                           xrce_dds_entry,
                           RT_NULL,
                           1024*3,
                           PRIORITY_DDS,
                           2);
    
    if (thread_dds_handle != NULL) {
        res = rt_thread_startup(thread_dds_handle);
    }

    return res;
}
INIT_APP_EXPORT(task_dds_init);
/*------------------------------------test------------------------------------*/


